/* 
  堆内存：
    对象数据类型或者函数数据类型在定义的时候首先都会开辟一个堆内存，堆内存
    有一个引用地址，如果外面有变量等知道了这个地址，我们就说这个内存被占用了
    就不能销毁了
*/

var obj1 = {
  name: '张三'
}

var obj2 = obj1;

/* 
  我们想要让堆内存释放/销毁，只需要把所有引用他的变量值赋值为null即可，如果
  当前的堆内存没有任何东西被占用了，那么浏览器会在空闲的时候把它销毁...
*/
obj1 = null;
obj2 = null;


/* 
  栈内存：
    1)全局作用域
      只有当页面关闭的时候全局作用域才会销毁

    2)私有作用域（只有函数执行会产生私有的作用域）
      一般情况下，函数执行会形成一个新的私有的作用域，当私有作用域中的代码执行完成
      后，我们当前作用域都会主动的进行释放和销毁
      但是还是存在特殊的情况的：
      当前私有作用域中的部分内存被作用域以外的东西占用了，那么当前的这个
      作用域就不能被销毁了
*/

// a、函数执行返回了一个引用数据类型的值，并且在函数的外面被一个其他的东西
// 给接收了，这种情况下一般形成的私有作用域都不会销毁
function fn() {
  var num = 100;
  return function () {}
}

var f = fn(); // fn执行形成的这个私有的作用域就不能被销毁了

// b、在一个私有的作用域中给DOM元素的事件绑定方法，一般情况下我们的私有作用域
// 都不销毁
var oDiv = document.getElementById("div1");
~ function () {
  oDiv.onclick = function () {

  }
}(); // 当前自执行函数形成的这个私有的作用域也不销毁


// c、下述情况属于不立即销毁 -> fn返回的函数没有被其他的东西占用，但是还需要
// 执行一次呢，所以暂时不销毁，当返回的值执行完成后，浏览器会在空闲的时候把它销毁 -> "不立即销毁"
function fn() {
  var num = 100;
  return function () {}
}

fn()(); // 首先执行fn，返回一个小函数对应的内存地址，然后紧接着让返回的小函数再执行